package org.cboard.security.shiro;

import javax.annotation.PostConstruct;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.cboard.controller.LoginController;
import org.cboard.dto.User;
import org.cboard.security.service.DbUserDetailService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class SystemAuthorizingRealm extends AuthorizingRealm {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private DbUserDetailService dbUserDetailService;

    /**
     * 认证回调函数, 登录时调用
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) {
	UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
	// 校验用户名密码
	User user = (User) dbUserDetailService.loadUserByUsername(token.getUsername());
	if (user != null) {
	    // if (Global.NO.equals(user.getLoginFlag())) {
	    // throw new AuthenticationException("msg:该帐号已禁止登录.");
	    // }
	    return new SimpleAuthenticationInfo(token.getUsername(), user.getPassword().toCharArray(), getName());
	} else {
	    return null;
	}
    }

    /**
     * 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
	String loginName = (String) principals.getPrimaryPrincipal();
	// 获取当前已登录的用户
	User user = (User) dbUserDetailService.loadUserByUsername(loginName);
	if (user != null) {
	    SecurityUtils.getSubject().getSession().setAttribute(LoginController.SESSION_LOGIN_USER,user);
	    SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//	    List<Menu> list = UserUtils.getMenuList();
//	    for (Menu menu : list) {
//		if (StringUtils.isNotBlank(menu.getPermission())) {
//		    // 添加基于Permission的权限信息
//		    for (String permission : StringUtils.split(menu.getPermission(), ",")) {
//			info.addStringPermission(permission);
//		    }
//		}
//	    }
	    // 添加用户权限
	    info.addStringPermission("user");
	    // 添加用户角色信息
//	    for (Role role : user.getRoleList()) {
//		info.addRole(role.getEnname());
//	    }
	    return info;
	} else {
	    return null;
	}
    }

    /**
     * 设定密码校验的Hash算法与迭代次数
     */
    @PostConstruct
    public void initCredentialsMatcher() {
	HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(Md5Hash.ALGORITHM_NAME);
	matcher.setStoredCredentialsHexEncoded(true);
	setCredentialsMatcher(matcher);
    }
}
